home *** CD-ROM | disk | FTP | other *** search
- /*
- File: file.c
-
- Copyright: © 1997 by Apple Computer, Inc., all rights reserved.
-
- */
-
- #pragma segment DocSeg
-
- #ifndef __STRINGS__
- #include <Strings.h>
- #endif
-
- #ifndef __STDIO__
- #include <StdIO.h>
- #endif
-
- #ifndef __FINDER__
- #include "Finder.h"
- #endif
-
- #ifndef __NAVIGATION__
- #include "Navigation.h"
- #endif
-
- #ifndef Common_Defs
- #include "Common.h"
- #endif
-
- const long kPictHeaderSize = 512;
-
- short ReadFile(Document* theDocument);
- short WriteFile(Document* theDocument);
- short WriteNewFile(Document* theDocument, FSSpec* newFileSpec);
- pascal Boolean myFilterProc(AEDesc *theItem, void *info, NavCallBackUserData callBackUD);
-
- extern Document* gDocumentList[kMaxDocumentCount];
-
-
- // *****************************************************************************
- // *
- // * ReadFile()
- // *
- // *****************************************************************************
- short ReadFile(Document* theDocument)
- {
- long count;
- short theResult;
- char buffer[256];
- TextStyle theStyle;
-
- SetCursor(*GetCursor(watchCursor));
-
- if (theDocument->theTE != NULL)
- {
- TESetSelect(0,(**(theDocument->theTE)).teLength,theDocument->theTE);
- TEDelete(theDocument->theTE);
-
- if (theResult = SetFPos(theDocument->fRefNum,fsFromStart,0))
- return theResult;
-
- do {
- count = 256;
- theResult = FSRead(theDocument->fRefNum,&count,&buffer);
- TEInsert(&buffer,count,theDocument->theTE);
- }
- while (theResult == noErr);
-
- TESetSelect(0,32767,theDocument->theTE);
- theStyle.tsFont = 21;
- theStyle.tsSize = 12;
- TESetStyle(doFont + doSize,&theStyle,true,theDocument->theTE);
- TESetSelect(0,0,theDocument->theTE);
- }
- else
- {
- short result = noErr;
- long fileSize = 0;
- long headerSize = 0;
- long pictSize = 0;
-
- SetCursor(*(Cursor**)GetCursor(watchCursor));
-
- if (theResult = SetFPos(theDocument->fRefNum,fsFromStart,0))
- return theResult;
-
- theResult = GetEOF(theDocument->fRefNum,&fileSize);
-
- theDocument->fPictLength = fileSize;
- theDocument->fPictLength -= kPictHeaderSize;
- theDocument->fPict = NewHandle(theDocument->fPictLength);
- theDocument->fHeader = NewHandle(kPictHeaderSize);
- if ((theDocument->fPict == NULL)||(theDocument->fPict == NULL))
- {
- SysBeep(5);
- return memFullErr;
- }
- headerSize = kPictHeaderSize;
- pictSize = theDocument->fPictLength;
-
- theResult = FSRead(theDocument->fRefNum,&headerSize,*theDocument->fHeader);
- theResult = FSRead(theDocument->fRefNum,&pictSize,*theDocument->fPict);
- }
-
- theDocument->dirty = false;
-
- return noErr;
- }
-
-
- // *****************************************************************************
- // *
- // * WriteFile()
- // *
- // *****************************************************************************
- short WriteFile(Document* theDocument)
- {
- short theResult;
- long length;
- char* bufPtr;
-
- SetCursor(*GetCursor(watchCursor));
-
- if (!theDocument->fRefNum)
- return fnOpnErr;
-
- if (theResult = SetFPos(theDocument->fRefNum,fsFromStart,0))
- return theResult;
-
- if (theDocument->theTE != NULL)
- {
- length = (**(theDocument->theTE)).teLength;
- bufPtr = *((**(theDocument->theTE)).hText);
-
- theResult = FSWrite(theDocument->fRefNum,&length,bufPtr);
- if (theResult == noErr)
- theResult = SetEOF(theDocument->fRefNum,length);
- }
- else
- {
- long headerSize = kPictHeaderSize;
- long pictSize = theDocument->fPictLength;
-
- theResult = FSWrite(theDocument->fRefNum,&headerSize,*theDocument->fHeader);
- if (theResult == noErr)
- {
- theResult = FSWrite(theDocument->fRefNum,&pictSize,*theDocument->fPict);
- if (theResult == noErr)
- theResult = SetEOF(theDocument->fRefNum,headerSize+pictSize);
- }
- }
-
- return theResult;
- }
-
-
- // *****************************************************************************
- // *
- // * WriteNewFile()
- // *
- // *****************************************************************************
- short WriteNewFile(Document* theDocument, FSSpec* newFileSpec)
- {
- short theResult;
- short refNum = 0;
-
- SetCursor(*GetCursor(watchCursor));
-
- theResult = FSpOpenDF(newFileSpec,fsRdWrPerm,&refNum);
- if (refNum != -1)
- {
- if (theResult = SetFPos(refNum,fsFromStart,0))
- return(theResult);
-
- if (theDocument->theTE != NULL)
- {
- long length;
- char* bufPtr;
- length = (**(theDocument->theTE)).teLength;
- bufPtr = *((**(theDocument->theTE)).hText);
-
- if (theResult = FSWrite(refNum,&length,bufPtr))
- return(theResult);
-
- theResult = SetEOF(refNum,length);
- }
- else
- {
- long headerSize = kPictHeaderSize;
- long pictSize = theDocument->fPictLength;
-
- theResult = FSWrite(refNum,&headerSize,*theDocument->fHeader);
- theResult = FSWrite(refNum,&pictSize,*theDocument->fPict);
-
- theResult = SetEOF(refNum,headerSize+pictSize);
- }
- theResult = FSClose(refNum);
- }
- return theResult;
- }
-
-
- // *****************************************************************************
- // *
- // * DoNewDocument()
- // *
- // *****************************************************************************
- void DoNewDocument(Boolean newDocAsPICT)
- {
- Document* theDocument;
- if (theDocument = NewDocument(newDocAsPICT))
- ShowWindow(theDocument->theWindow);
- }
-
-
- // *****************************************************************************
- // *
- // * DoOpenFile()
- // *
- // *****************************************************************************
- OSErr DoOpenFile(FSSpec* theFile, Boolean openAsPICT)
- {
- OSErr result;
- short refNum;
- Document* theDocument;
-
- if (result = FSpOpenDF(theFile,fsRdWrPerm,&refNum))
- return(result);
-
- if (theDocument = NewDocument(openAsPICT))
- {
- theDocument->fRefNum = refNum;
- if (ReadFile(theDocument))
- SysBeep(5);
-
- SetWTitle(theDocument->theWindow,theFile->name);
- SizeDocWindow(theDocument);
-
- AdjustScrollBar(theDocument);
- ShowWindow(theDocument->theWindow);
- }
- else
- {
- SysBeep(1);
- FSClose(refNum);
- return(memFullErr);
- }
- return noErr;
- }
-
-
- // *****************************************************************************
- // *
- // * myFilterProc()
- // *
- // * If user choose "none" for 'open' resoure filtering, this routine could
- // * affect the filter if used!
- // *
- // *****************************************************************************
- pascal Boolean myFilterProc(AEDesc* theItem, void* info, NavCallBackUserData /*callBackUD*/)
- {
- OSErr theErr = noErr;
- Boolean display = false;
- NavFileOrFolderInfo* theInfo;
-
- if (theItem->descriptorType == typeFSS)
- {
- theInfo = (NavFileOrFolderInfo*)info;
- if (((theInfo->isFolder) && (theInfo->visible)) ||
- ((theInfo->u.fileInfo.finderInfo.fdFlags & kIsAlias) != 0))
- display = true; // item is a visible folder (normal or aliased)
- else
- switch (theInfo->u.fileInfo.finderInfo.fdType)
- {
- case 'TEXT':
- case 'PICT':
- display = true;
- break;
- default:
- display = false;
- break;
- }
- }
- return display;
- }
-
-
- // *****************************************************************************
- // *
- // * myEventProc()
- // *
- // *****************************************************************************
- pascal void myEventProc(const NavEventCallbackMessage callBackSelector,
- NavCBRecPtr callBackParms,
- NavCallBackUserData callBackUD)
- {
- WindowPtr pWindow = NULL;
- Document** docList;
- Document* theDoc = NULL;
- short index = 0;
-
- if ((callBackUD != 0)&&(callBackSelector == kNavCBEvent))
- {
- docList = (Document**)callBackUD;
-
- if (docList != NULL)
- switch (callBackParms->event->what)
- {
- case nullEvent:
- break;
-
- case updateEvt:
- pWindow = (WindowPtr)callBackParms->event->message;
- theDoc = docList[index];
- if (theDoc != NULL)
- {
- while ((theDoc->theWindow != pWindow) && (docList[index] != NULL))
- {
- index++;
- theDoc = docList[index];
- }
- theDoc = docList[index];
- if (theDoc != NULL)
- UpdateWindow(theDoc);
- }
- break;
-
- case activateEvt:
- break;
-
- default:
- break;
- }
- }
- }
-
-
- // *****************************************************************************
- // *
- // * DoOpenDocumentTheOldWay()
- // *
- // *****************************************************************************
- OSErr DoOpenDocumentTheOldWay()
- {
- OSErr theErr = noErr;
- //••
- return theErr;
- }
-
-
- // *****************************************************************************
- // *
- // * DoOpenDocument()
- // *
- // *****************************************************************************
- OSErr DoOpenDocument()
- {
- NavReplyRecord theReply;
- NavDialogOptions dialogOptions;
- OSErr theErr = noErr;
- Handle openRsrc = NULL;
- long count = 0;
- NavEventProcUPP eventProcUPP = NewNavEventProc(myEventProc);
- NavObjectFilterProcUPP filterProcUPP = NewNavObjectFilterProc(myFilterProc);
-
- // default behavior for browser and dialog:
- theErr = NavGetDefaultDialogOptions(&dialogOptions);
- dialogOptions.allowPreviews = true;
-
- GetIndString((unsigned char*)&dialogOptions.applicationName,FileStringsID,sApplicationName);
-
- openRsrc = GetResource(kOpenRsrcType,kOpenRsrcID);
- if ((openRsrc != NULL)&&(ResError() == noErr))
- HLock((Handle)openRsrc);
-
- dialogOptions.preferenceKey = kOpenPrefKey;
-
- theErr = NavGetFile(NULL, // use system's default location
- &theReply,
- &dialogOptions,
- eventProcUPP,
- NULL, // no custom previews
- (NavCallBackUserData)&gDocumentList,
- openRsrc,
- filterProcUPP);
-
- DisposeRoutineDescriptor(eventProcUPP);
- DisposeRoutineDescriptor(filterProcUPP);
-
- if ((theReply.validRecord)&&(theErr == noErr))
- {
- // since we allow for multiple objects to be returned,
- // grab the target FSSpecs from 'theReply.fileRef' list for opening:
- FSSpec finalFSSpec;
- AEDesc resultDesc;
- FInfo fileInfo;
-
- // in the case we didn't want built in translation:
- if ((dialogOptions.dialogOptionFlags & kDontAutoTranslate) != 0)
- if (theReply.translationNeeded)
- {
- // if we didn't want built in translation it was for the following reasons:
- // 1) we want to do it ourselves
- // 2) or we want to defer it
- // things to remember if auto-translation is turned off:
- // 1) the AEDesc list contains the original file specs the user had chosen.
- // 2) the 'fileTranslation' field for each object that needs translation has filled in for you.
-
- // put your own code here to perform your own translation.
- // - or -
- // we can simply call this to perform the translation manually:
- theErr = NavTranslateFile(&theReply,kNavTranslateCopy);
- }
-
- // we are ready to open the document(s),
- // grab information about each file for opening:
- theErr = AECountItems(&(theReply.selection),&count);
- for (long index=1;index<=count;index++)
- {
- resultDesc.dataHandle = 0L;
- theErr = AEGetNthDesc(&(theReply.selection),index,typeFSS,NULL,&resultDesc);
- if (theErr == noErr)
- {
- BlockMoveData(*resultDesc.dataHandle,&finalFSSpec,sizeof(FSSpec));
-
- // decide if the doc we are opening is a 'PICT' or 'TEXT':
- theErr = FSpGetFInfo(&finalFSSpec,&fileInfo);
- if (theErr == noErr)
- {
- if (fileInfo.fdType == kFileType)
- DoOpenFile(&finalFSSpec,false);
- else
- if (fileInfo.fdType == kFileTypePICT)
- DoOpenFile(&finalFSSpec,true);
- else
- {
- // error:
- // if we got this far, the document is a type we can't open and
- // (most likely) built-in translation was turned off.
- // You can alert the user that this returned selection or file spec
- // needs translation.
- }
- }
- theErr = AEDisposeDesc(&resultDesc);
- }
- }
- theErr = NavDisposeReply(&theReply);
- }
-
- if (openRsrc != NULL)
- {
- HUnlock((Handle)openRsrc);
- ReleaseResource((Handle)openRsrc);
- }
-
- return theErr;
- }
-
-
- // *****************************************************************************
- // *
- // * SaveACopyDocumentTheOldWay()
- // *
- // *****************************************************************************
- OSErr SaveACopyDocumentTheOldWay(Document* /*theDocument*/)
- {
- //••
- return noErr;
- }
-
-
- // *****************************************************************************
- // *
- // * SaveACopyDocument()
- // *
- // *****************************************************************************
- OSErr SaveACopyDocument(Document* theDocument)
- {
- OSErr theErr = noErr;
- NavReplyRecord theReply;
- NavDialogOptions dialogOptions;
- NavEventProcUPP eventProcUPP = NewNavEventProc(myEventProc);
- Str255 docTitle;
- OSType fileTypeToSave;
-
- GetIndString((unsigned char*)&dialogOptions.applicationName,FileStringsID,sApplicationName);
-
- // default behavior for browser and dialog:
- theErr = NavGetDefaultDialogOptions(&dialogOptions);
-
- GetWTitle(theDocument->theWindow,docTitle);
- p2cstr((StringPtr)docTitle);
- sprintf((char*)dialogOptions.savedFileName,(char*)"%s copy",docTitle);
- c2pstr((Ptr)dialogOptions.savedFileName);
-
- if (theDocument->theTE != NULL)
- fileTypeToSave = kFileType;
- else
- fileTypeToSave = kFileTypePICT;
-
- dialogOptions.preferenceKey = kSavePrefKey;
-
- theErr = NavPutFile(NULL, // use system's default location
- &theReply,
- &dialogOptions,
- eventProcUPP,
- (NavCallBackUserData)&gDocumentList,
- fileTypeToSave,
- kFileCreator);
-
- DisposeRoutineDescriptor(eventProcUPP);
-
- if ((theReply.validRecord)&&(theErr == noErr))
- {
- FSSpec finalFSSpec;
- AEDesc resultDesc;
- resultDesc.dataHandle = 0L;
-
- // retrieve the returned selection:
- // since only 1 selection is possible, we get the first AEDesc:
- theErr = AEGetNthDesc(&(theReply.selection),1,typeFSS,NULL,&resultDesc);
- if (theErr == noErr)
- {
- BlockMoveData(*resultDesc.dataHandle,&finalFSSpec,sizeof(FSSpec));
-
- if (theReply.replacing)
- theErr = FSpDelete(&finalFSSpec);
- if (theErr == noErr)
- {
- theErr = FSpCreate(&finalFSSpec,kFileCreator,fileTypeToSave,smSystemScript);
- if (theErr == noErr)
- {
- theErr = WriteNewFile(theDocument,&finalFSSpec); // use this document's data to write to our new copy
- if (theErr == noErr)
- {
- if (theReply.translationNeeded)
- {
- // translation is needed for file we are saving a copy of:
- if (theErr == noErr)
- // when you save a copy, you should always "translate in place":
- theErr = NavCompleteSave(&theReply,kNavTranslateInPlace);
- }
- }
- }
- }
- else
- if (theErr == fBsyErr)
- DebugStr("\perror: file is busy, can't write"); //•• need alert
- }
- theErr = NavDisposeReply(&theReply);
- }
-
- return theErr;
- }
-
-
- // *****************************************************************************
- // *
- // * DoSaveDocument()
- // *
- // *****************************************************************************
- short DoSaveDocument(Document* theDocument)
- {
- if (!theDocument)
- return false;
-
- if (theDocument->fRefNum)
- {
- if (WriteFile(theDocument))
- {
- SysBeep(5);
- return false;
- }
- else
- theDocument->dirty = false;
- return true;
- }
- else
- {
- //•• need SaveACopy replica here: return(SaveAsDocument(theDocument));
- //•• also, these routines should return OSErr!
- return true;
- }
- }
-
-
- // *****************************************************************************
- // *
- // * DoRevertDocument()
- // *
- // *****************************************************************************
- void DoRevertDocument(Document* theDocument)
- {
- if (!theDocument)
- return;
-
- if (theDocument->fRefNum)
- {
- OSErr theErr = noErr;
- NavEventProcUPP eventProcUPP = NewNavEventProc(myEventProc);
- NavAskDiscardChangesResult reply;
- Str255 theName;
-
- GetWTitle(theDocument->theWindow,(unsigned char*)&theName);
- theErr = NavAskDiscardChanges( theName,
- &reply,
- eventProcUPP,
- (NavCallBackUserData)&gDocumentList);
-
- DisposeRoutineDescriptor(eventProcUPP);
-
- switch (reply)
- {
- case askDiscardChanges:
- if (ReadFile(theDocument))
- SysBeep(5);
- break;
-
- case askDiscardChangesCancel:
- break;
- }
- }
- }
-
- // *****************************************************************************
- // *
- // * DoRevertDocumentTheOldWay()
- // *
- // *****************************************************************************
- void DoRevertDocumentTheOldWay(Document* theDocument)
- {
- Str255 theName;
-
- if (!theDocument)
- return;
-
- if (theDocument->fRefNum)
- {
- GetWTitle(theDocument->theWindow,(unsigned char*)&theName);
- ParamText((ConstStr255Param)&theName,(ConstStr255Param)"\p",(ConstStr255Param)"\p",(ConstStr255Param)"\p");
- if (Alert(idRevertALRT,0L) == 1)
- if (ReadFile(theDocument))
- SysBeep(5);
- }
- }
-
-
-